home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / fonttools / totype1.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  14KB  |  616 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *      totype1: convert an outline font into a PostScript font.
  19.  *        
  20.  *        Paul Haeberil and Seth Teller
  21.  *
  22.  */
  23. #include "math.h"
  24. #include "ctype.h"
  25. #include "stdio.h"
  26. #include "objfnt.h"
  27.  
  28. static void makefontname();
  29. static void writepsfile();
  30.  
  31. main(argc,argv)
  32. int argc;
  33. char **argv;
  34. {
  35.     objfnt *fnt;
  36.     char fontname[256];
  37.  
  38.     if( argc<3 ) {
  39.     fprintf(stderr,"usage: totype1 font.of type1font [font.afm]\n");
  40.     exit(1);
  41.     }
  42.     fnt = readobjfnt(argv[1]);
  43.     if(!fnt ) {
  44.     fprintf(stderr,"totype1: can't open input font\n");
  45.     exit(1);
  46.     } 
  47.     if(fnt->type != PO_TYPE && fnt->type != SP_TYPE) {
  48.     fprintf(stderr,"totype1: input font must be Polygon or Spline outline\n");
  49.     exit(1);
  50.     }
  51.     makefontname(argv[2],fontname);
  52.     writepsfile(fnt,fontname,argv[2]);
  53.     if(argc>3)
  54.     writeafmfile(fnt,fontname,argv[3]);
  55.     exit(0);
  56. }
  57.  
  58. #define DATABUFLEN    (32)
  59. static unsigned char databuf[DATABUFLEN];
  60. #define MAXPROGLEN    (4096)
  61. static unsigned char type1prog[MAXPROGLEN];
  62.  
  63. #define NOTDEFLEN    (9)
  64. static unsigned char notdefprog[NOTDEFLEN] = {
  65.     0x00, 0x01, 0x02, 0x03,
  66.     0x8b, 0xf7, 0x8e, 0x0d, 0x0e,
  67. };
  68.  
  69. static int firsted;
  70.  
  71. /*
  72.  *    program opcodes:
  73.  *
  74.  *
  75.  */
  76. #define HSTEM        (1)
  77. #define VSTEM        (3)
  78. #define VMOVETO        (4)
  79. #define RLINETO        (5)
  80. #define HLINETO        (6)
  81. #define VLINETO        (7)
  82. #define RRCURVETO    (8)
  83. #define CLOSEPATH    (9)
  84. #define CALLSUBR    (10)
  85. #define RETURN        (11)
  86. #define HSBW        (13)
  87. #define ENDCHAR        (14)
  88. #define RMOVETO        (21)
  89. #define HMOVETO        (22)
  90. #define VHCURVETO    (30)
  91. #define HVCURVETO    (31)
  92. #define DOTSECTION    (256+0)
  93. #define VSTEM3        (256+1)
  94. #define HSTEM3        (256+2)
  95. #define SEAC        (256+6)
  96. #define SBW        (256+7)
  97. #define DIV        (256+12)
  98. #define CALLOTHERSUBR    (256+16)
  99. #define POP        (256+17)
  100. #define SETCURRENTPOINT    (256+33)
  101. #define WHAT0        (0)
  102.  
  103. /*
  104.  *    Encryption support
  105.  *
  106.  */
  107. static unsigned short mr;
  108.  
  109. static void resetencrypt(int n)
  110. {
  111.     mr = n;
  112. }
  113.  
  114. static void encryptdata(unsigned char *iptr,unsigned char *optr,int n)
  115. {
  116.     unsigned char in;
  117.     unsigned short mymr;
  118.     unsigned short c1;
  119.     unsigned short c2;
  120.  
  121.     mymr = mr;
  122.     c1 = 52845;
  123.     c2 = 22719;
  124.     while(n>8) {
  125.     in = iptr[0];
  126.     optr[0] = (in^(mymr>>8));
  127.     mymr = (optr[0]+mymr)*c1 + c2;
  128.     in = iptr[1];
  129.     optr[1] = (in^(mymr>>8));
  130.     mymr = (optr[1]+mymr)*c1 + c2;
  131.     in = iptr[2];
  132.     optr[2] = (in^(mymr>>8));
  133.     mymr = (optr[2]+mymr)*c1 + c2;
  134.     in = iptr[3];
  135.     optr[3] = (in^(mymr>>8));
  136.     mymr = (optr[3]+mymr)*c1 + c2;
  137.     in = iptr[4];
  138.     optr[4] = (in^(mymr>>8));
  139.     mymr = (optr[4]+mymr)*c1 + c2;
  140.     in = iptr[5];
  141.     optr[5] = (in^(mymr>>8));
  142.     mymr = (optr[5]+mymr)*c1 + c2;
  143.     in = iptr[6];
  144.     optr[6] = (in^(mymr>>8));
  145.     mymr = (optr[6]+mymr)*c1 + c2;
  146.     in = iptr[7];
  147.     optr[7] = (in^(mymr>>8));
  148.     mymr = (optr[7]+mymr)*c1 + c2;
  149.     n-=8;
  150.     optr+=8;
  151.     iptr+=8;
  152.     }
  153.     while(n--) {
  154.     in = iptr[0];
  155.     optr[0] = (in^(mymr>>8));
  156.     mymr = (optr[0]+mymr)*c1 + c2;
  157.     optr++;
  158.     iptr++;
  159.     }
  160.     mr = mymr;
  161. }
  162.  
  163. static int encryptprogram(unsigned char *buf,int len)
  164. {
  165.     resetencrypt(4330);
  166.     encryptdata(buf,buf,len);
  167. }
  168.  
  169. static void makefontname(filename,fontname)
  170. char *filename, *fontname;
  171. {
  172.     int n;
  173.     char *cptr, *slashptr, *dptr;
  174.  
  175.     cptr = filename;
  176.     slashptr = 0;
  177.     while(*cptr) {
  178.     if(*cptr == '/')
  179.         slashptr = cptr;
  180.     cptr++;
  181.     }
  182.     if(slashptr)
  183.     cptr = slashptr+1;
  184.     else
  185.     cptr = filename;
  186.     dptr = fontname;
  187.     while(*cptr) {
  188.     if(*cptr == '.')
  189.         break;
  190.     *dptr++ = *cptr++;
  191.     }
  192.     *dptr = 0;
  193. }
  194.  
  195. static int makeid(name)
  196. unsigned char *name;
  197. {
  198.     int hash;
  199.  
  200.     hash = 0;
  201.     while(*name) {
  202.     hash = (hash<<1)^(*name++);
  203.     }
  204.     hash = hash%20000;
  205.     return hash+40000;
  206. }
  207.  
  208. static void puthexdata(outf,buf,n)
  209. FILE *outf;
  210. unsigned char *buf;
  211. int n;
  212. {
  213.     while(n--) 
  214.      fprintf(outf,"%02x",*buf++);
  215.      fprintf(outf,"\n");
  216. }
  217.  
  218. static unsigned char *outpos;
  219. static int curx, cury;
  220.  
  221. static void OP_PUSHVAL(val)
  222. int val;
  223. {
  224.     int high;
  225.  
  226.     if(val>=-107 && val<=107) {
  227.      *outpos++ = val+139;
  228.     } else if(val>0 && val<=1131) {
  229.     val = val-108;
  230.     high = val/256;
  231.     *outpos++ = 247+high;
  232.     *outpos++ = val-(256*high);
  233.     } else if(val<0 && val>=-1131) {
  234.     val = -val;
  235.     val = val-108;
  236.     high = val/256;
  237.     *outpos++ = 251+high;
  238.     *outpos++ = val-(256*high);
  239.     } else {
  240.     *outpos++ = 255;
  241.     *outpos++ = (val>>24)&0xff;
  242.     *outpos++ = (val>>16)&0xff;
  243.     *outpos++ = (val>> 8)&0xff;
  244.     *outpos++ = (val>> 0)&0xff;
  245.     }
  246. }
  247.  
  248. static void OP_ADDSALT()
  249. {
  250.     *outpos++ = 0x00;
  251.     *outpos++ = 0x01;
  252.     *outpos++ = 0x02;
  253.     *outpos++ = 0x03;
  254. }
  255.  
  256. static void OP_ENDCHAR()
  257. {
  258.     *outpos++ = ENDCHAR;
  259. }
  260.  
  261. static void OP_RMOVETO(dx,dy)
  262. int dx, dy;
  263. {
  264.     OP_PUSHVAL(dx);
  265.     OP_PUSHVAL(dy);
  266.     *outpos++ = RMOVETO;
  267.     curx = curx+dx;
  268.     cury = cury+dy;
  269. }
  270.  
  271. static void OP_RLINETO(dx,dy)
  272. int dx, dy;
  273. {
  274.     OP_PUSHVAL(dx);
  275.     OP_PUSHVAL(dy);
  276.     *outpos++ = RLINETO;
  277.     curx = curx+dx;
  278.     cury = cury+dy;
  279. }
  280.  
  281. static void OP_CLOSEPATH()
  282. {
  283.     *outpos++ = CLOSEPATH;
  284. }
  285.  
  286. static void OP_ADVANCE(width)
  287. int width;
  288. {
  289.     OP_PUSHVAL(0);
  290.     OP_PUSHVAL(width);
  291.     *outpos++ = HSBW;
  292.     curx = cury = 0;
  293. }
  294.  
  295. static void OP_MOVETO(x,y)
  296. int x, y; 
  297. {
  298.     OP_RMOVETO(x-curx,y-cury);
  299. }
  300.  
  301. static void OP_LINETO(x,y)
  302. int x, y; 
  303. {
  304.     OP_RLINETO(x-curx,y-cury);
  305. }
  306.  
  307. static void OP_RRCURVETO(x1,y1,x2,y2,x3,y3)
  308. int x1, y1, x2, y2, x3, y3;
  309. {
  310.     OP_PUSHVAL(x1);
  311.     OP_PUSHVAL(y1);
  312.     OP_PUSHVAL(x2);
  313.     OP_PUSHVAL(y2);
  314.     OP_PUSHVAL(x3);
  315.     OP_PUSHVAL(y3);
  316.     *outpos++ = RRCURVETO;
  317.     curx = curx+x1+x2+x3;
  318.     cury = cury+y1+y2+y3;
  319. }
  320.  
  321. static void OP_CURVETO(x1,y1,x2,y2,x3,y3)
  322. int x1, y1, x2, y2, x3, y3;
  323. {
  324.     int dx1, dy1, dx2, dy2, dx3, dy3;
  325.     int x0, y0;
  326.  
  327.     x0 = curx;
  328.     y0 = cury;
  329.     dx1 = x1-x0;
  330.     dy1 = y1-y0;
  331.     dx2 = x2-x0;
  332.     dy2 = y2-y0;
  333.     dx3 = x3-x0;
  334.     dy3 = y3-y0;
  335.  
  336.     dx3 = dx3-dx2;
  337.     dy3 = dy3-dy2;
  338.     dx2 = dx2-dx1;
  339.     dy2 = dy2-dy1;
  340.  
  341.     OP_RRCURVETO(dx1,dy1,dx2,dy2,dx3,dy3);
  342. }
  343.  
  344. static int maketype1prog(prog,type,advance,type1prog)
  345. short *prog;
  346. int type, advance;
  347. unsigned char *type1prog;
  348. {
  349.     int nverts, npoints;
  350.     unsigned char *initpos; 
  351.     short *sptr;
  352.  
  353.     outpos = type1prog;
  354.  
  355.     OP_ADDSALT();
  356.     OP_ADVANCE(advance);
  357.  
  358.     sptr = prog;
  359.     switch(type) {
  360.     case PO_TYPE:
  361.         npoints = 0;
  362.         while(1) {
  363.         switch(*sptr++) {    
  364.             case PO_BGNLOOP:
  365.             npoints = 0;
  366.             break;
  367.             case PO_ENDBGNLOOP:
  368.             OP_CLOSEPATH();
  369.             npoints = 0;
  370.             break;
  371.             case PO_RETENDLOOP:
  372.             case PO_RET:
  373.             OP_CLOSEPATH();
  374.             OP_ENDCHAR();
  375.             return outpos-type1prog;
  376.             break;
  377.         }
  378.         nverts = *sptr++;
  379.         while(nverts--) {
  380.             if(npoints == 0) 
  381.             OP_MOVETO(sptr[0],sptr[1]);
  382.             else
  383.             OP_LINETO(sptr[0],sptr[1]);
  384.             sptr+=2;
  385.             npoints++;
  386.         }
  387.         }
  388.     case SP_TYPE:
  389.         while(1) {
  390.         switch(*sptr++) {    
  391.             case SP_MOVETO:
  392.             OP_MOVETO(sptr[0],sptr[1]);
  393.             sptr+=2;
  394.             break;
  395.             case SP_LINETO:
  396.             OP_LINETO(sptr[0],sptr[1]);
  397.             sptr+=2;
  398.             break;
  399.             case SP_CURVETO:
  400.             OP_CURVETO(sptr[0],sptr[1],
  401.                    sptr[2],sptr[3],sptr[4],sptr[5]);
  402.             sptr+=6;
  403.             break;
  404.             case SP_CLOSEPATH:
  405.             OP_CLOSEPATH();
  406.             break;
  407.             case SP_RETCLOSEPATH:
  408.             OP_CLOSEPATH();
  409.             OP_ENDCHAR();
  410.             return outpos-type1prog;
  411.             break;
  412.             case SP_RET:
  413.             OP_ENDCHAR();
  414.             return outpos-type1prog;
  415.             break;
  416.             default:
  417.             printf("bad op %d\n",sptr[-1]);
  418.             break;
  419.         }
  420.         }
  421.     }
  422. }
  423.  
  424. static void writepsfile(fnt,fontname,outfname)
  425. objfnt *fnt;
  426. char *fontname, *outfname;
  427. {
  428.     int i, c, nbytes;
  429.     char tempfilename[256];
  430.     char cmd[256];
  431.     FILE *outf, *cf;
  432.     chardesc *cd;
  433.     short *prog;
  434.     int ndefined;
  435.     int llx, lly, urx, ury;
  436.  
  437.     if(!firsted) {
  438.     encryptprogram(notdefprog,NOTDEFLEN);
  439.     firsted = 1;
  440.     }
  441.     outf = fopen(outfname,"w");
  442.     if(!outf) {
  443.         fprintf(stderr,"totype1: can't open '%s' for write!\n",outfname);
  444.     exit(1);
  445.     }
  446.     fontbbox(fnt,&llx,&lly,&urx,&ury);
  447.  
  448. /* Put out EPSF header */
  449.     fprintf(outf,"%%!PS-AdobeFont-2.0: %s 001.001\n\n",fontname);
  450.     fprintf(outf,"%% To load to VM, remove the '%' character from the 'exitserver' line.\n\n");
  451.     fprintf(outf,"%% serverdict begin 0 exitserver %% for VM installation\n\n");
  452.  
  453. /* emit the obligatory header code */
  454.     fprintf(outf,"11 dict begin\n");
  455.     fprintf(outf,"/FontInfo 10 dict dup begin\n");
  456.     fprintf(outf,"version (001.000) readonly def\n");
  457.     fprintf(outf,"/Notice (Adobe Type 1 format font) readonly def\n");
  458.     fprintf(outf,"/Copyright (This is a spot for a copywrite notice) readonly def\n");
  459.     fprintf(outf,"/FullName (SGI %s) readonly def\n",fontname);
  460.     fprintf(outf,"/FamilyName (SGI %s) readonly def\n",fontname);
  461.     fprintf(outf,"/Weight (Medium) readonly def\n");
  462.     fprintf(outf,"/ItalicAngle 0 def\n");
  463.     fprintf(outf,"/isFixedPitch false def\n");
  464.     fprintf(outf,"/UnderlinePosition -110 def\n");
  465.     fprintf(outf,"/UnderlineThickness 49 def\n");
  466.     fprintf(outf,"end readonly def\n");
  467.     fprintf(outf,"/FontName /%s def\n",fontname);
  468.     fprintf(outf,"/Encoding StandardEncoding def\n");
  469.     fprintf(outf,"/PaintType 0 def\n");
  470.     fprintf(outf,"/FontType 1 def\n");
  471.     fprintf(outf,"/FontMatrix [%g 0 0 %g 0 0] readonly def\n",
  472.                       1.0/fnt->scale,1.0/fnt->scale);
  473.     fprintf(outf,"/UniqueID %d def\n",makeid(fontname));
  474.     fprintf(outf,"/FontBBox{%d %d %d %d}readonly def\n",llx,lly,urx,ury);
  475.     fprintf(outf,"currentdict end\n");
  476.     fprintf(outf,"currentfile eexec\n");
  477.  
  478. /* write out the encrypted part of the font */
  479.     sprintf(tempfilename,"/usr/tmp/totpy1XXXXXX");
  480.     mktemp(tempfilename);
  481.     cf = fopen(tempfilename,"w");
  482.     if(!cf) {
  483.         fprintf(stderr,"totype1: can't open 'temp.cf' for write!\n");
  484.     exit(1);
  485.     }
  486.     fprintf(cf,"ABCD");        /* four bytes ignored */
  487.     fprintf(cf,"dup /Private 8 dict dup begin\n");
  488.     fprintf(cf,"/-|{string currentfile exch readstring pop}executeonly def\n");
  489.     fprintf(cf,"/|-{noaccess def}executeonly def\n");
  490.     fprintf(cf,"/BlueValues [] def\n");
  491.     fprintf(cf,"/MinFeature{16 16}def\n");
  492.     fprintf(cf,"/password 5839 def\n");
  493.     fprintf(cf,"/ForceBold false def\n");
  494.     fprintf(cf,"/Subrs 0 array\n");
  495.     fprintf(cf,"|-\n");
  496.  
  497. /* define the encoding vector entries */
  498.     ndefined = 0;
  499.     ndefined++;     /* space = special case */
  500.     for(c = MIN_ASCII+1; c <= MAX_ASCII; c++) {
  501.         if(getcharprog(fnt,c)) 
  502.           ndefined++;
  503.     }
  504.  
  505.     fprintf(cf,"2 index /CharStrings %d dict dup begin\n",ndefined+1);
  506.  
  507. /* loop over the characters to output */
  508.     for(c = MIN_ASCII; c <= MAX_ASCII; c++)  {
  509.         if(prog=getcharprog(fnt,c)) {
  510.         cd = getchardesc(fnt,c);
  511.         nbytes = maketype1prog(prog,fnt->type,cd->movex,type1prog);
  512.  
  513. #ifdef DEBUGGING
  514. fprintf(stdout,"char %s nbytes: %d \n",asciiname(c),nbytes);
  515. puthexdata(stdout, type1prog,nbytes);
  516. fprintf(stdout,"\n\n");
  517. #endif
  518.  
  519.         encryptprogram(type1prog,nbytes);
  520.         fprintf(cf,"/%s %d -| ",asciiname(c),nbytes);
  521.         fwrite(type1prog,nbytes,1,cf);
  522.         fprintf(cf," |-\n");
  523.     }
  524.     }
  525.     fprintf(cf,"/.notdef %d -| ",NOTDEFLEN);
  526.     fwrite(notdefprog,NOTDEFLEN,1,cf);
  527.     fprintf(cf," |-\n");
  528.  
  529.     fprintf(cf,"end\n");
  530.     fprintf(cf,"end\n");
  531.     fprintf(cf,"readonly put\n");
  532.     fprintf(cf,"noaccess put\n");
  533.     fprintf(cf,"dup/FontName get exch definefont pop\n");
  534.     fprintf(cf,"mark currentfile closefile\n");
  535.     fclose(cf);
  536.  
  537. /* open the date file and encrypt it into the output file */
  538.     cf = fopen(tempfilename,"r");
  539.     if(!cf) {
  540.         fprintf(stderr,"totype1: can't open 'temp.cf' for write!\n");
  541.     exit(1);
  542.     }
  543.     resetencrypt(55665);
  544.     while( (nbytes=fread(databuf,1,DATABUFLEN,cf))>0 ) {
  545.     encryptdata(databuf,databuf,nbytes);
  546.     puthexdata(outf,databuf,nbytes);
  547.     }
  548.     fclose(cf);
  549.     sprintf(cmd,"mv %s temp.log",tempfilename);
  550.     system(cmd);
  551.     unlink(tempfilename);
  552.  
  553.     for(i=0; i<8; i++)
  554.     fprintf(outf,"0000000000000000000000000000000000000000000000000000000000000000\n");
  555.     fprintf(outf,"cleartomark\n");
  556.     fclose(outf);
  557. }
  558.  
  559. writeafmfile(fnt,fontname,outfname)
  560. objfnt *fnt;
  561. char *fontname, *outfname;
  562. {
  563.     FILE *outf;
  564.     int nchars;
  565.     int c, llx, lly, urx, ury;
  566.     chardesc *cd;
  567.  
  568.     outf = fopen(outfname,"w");
  569.     if(!outf) {
  570.         fprintf(stderr,"totype1: can't open '%s' for write!\n",outfname);
  571.     exit(1);
  572.     }
  573.     fontbbox(fnt,&llx,&lly,&urx,&ury);
  574.  
  575.     fprintf(outf,"StartFontMetrics 2.0\n");
  576.     fprintf(outf,"Comment Generated by totype1 on Silicon Graphics IRIS\n");
  577.     fprintf(outf,"FontName %s\n",fontname);
  578.     fprintf(outf,"FullName %s\n",fontname);
  579.     fprintf(outf,"FamilyName %s\n",fontname);
  580.     fprintf(outf,"Weight standard\n");
  581.     fprintf(outf,"Notice Note that there is no notice\n");
  582.     fprintf(outf,"ItalicAngle 0.0\n");
  583.     fprintf(outf,"IsFixedPitch false\n");
  584.     fprintf(outf,"UnderlinePosition -110\n");
  585.     fprintf(outf,"UnderlineThickness 49\n");
  586.     fprintf(outf,"Version 001.000\n");
  587.     fprintf(outf,"EncodingScheme AdobeStandardEncoding\n");
  588.     fprintf(outf,"FontBBox %d %d %d %d\n",llx,lly,urx,ury);
  589.     fprintf(outf,"CapHeight 662\n");    /* xxx */
  590.     fprintf(outf,"XHeight 448\n");    /* xxx */
  591.     fprintf(outf,"Descender -217\n");    /* xxx */
  592.     fprintf(outf,"Ascender 682\n");    /* xxx */
  593.     nchars = fnt->charmax-fnt->charmin;
  594.     fprintf(outf,"StartCharMetrics %d\n",nchars);
  595.     for(c=fnt->charmin; c<=fnt->charmax; c++) {
  596.     cd = getchardesc(fnt,c);
  597.     if(cd->llx == NOBBOX) {
  598.         llx = 0;
  599.         lly = 0;
  600.         urx = 0;
  601.         ury = 0;
  602.     } else {
  603.         llx = cd->llx;
  604.         lly = cd->lly;
  605.         urx = cd->urx;
  606.         ury = cd->ury;
  607.     }
  608.     if(asciiname(c))
  609.         fprintf(outf,"C %d ; WX %d ; N %s ; B %d %d %d %d ;\n",
  610.             c,cd->movex,asciiname(c),llx,lly,urx,ury);
  611.     }
  612.     fprintf(outf,"EndCharMetrics\n");
  613.     fprintf(outf,"EndFontMetrics\n");
  614.     fclose(outf);
  615. }
  616.